package erwiki.ui.app.admin.dialogs.hierachychange;

import java.util.ArrayList;

import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.elwiki_data.WikiPage;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;

import erwiki.admin.internal.InitializeLoginDb;
import erwiki.api.core.Engine;
import erwiki.api.pages.PageManager;
import erwiki.api.providers.PageProvider;
import jakarta.inject.Inject;

/**
 * При выборе страниц-потомков из списка удаляется выбранная master-страница.
 * 
 * @author vfedorov
 */
public class HierarchSelectionyDialog extends Dialog {
	private static final long serialVersionUID = 2144281273849533859L;

	private Text textMasterPage;

	WikiPage masterPage;
	java.util.List<WikiPage> childrenPages = new ArrayList<>();

	private ListViewer listViewer;

	final private Engine engine;

	/**
	 * Create the dialog.
	 * 
	 * @param parentShell
	 */
	public HierarchSelectionyDialog(Shell parentShell) {
		super(parentShell);
		// workaround - получить сервис Engine.
		BundleContext bundleContext = FrameworkUtil.getBundle(InitializeLoginDb.class).getBundleContext();
	    ServiceReference<Engine> serviceReference = bundleContext.getServiceReference(Engine.class);
	    engine = (Engine) bundleContext.getService(serviceReference);
	}

	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText("Выбор страниц");
	}

	/**
	 * Create contents of the dialog.
	 * 
	 * @param parent
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite container = (Composite) super.createDialogArea(parent);
		container.setLayout(new GridLayout(3, false));

		{
			Label lblMasterPage = new Label(container, SWT.NONE);
			lblMasterPage.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
			lblMasterPage.setText("Владелец:");

			this.textMasterPage = new Text(container, SWT.BORDER | SWT.READ_ONLY);
			this.textMasterPage.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

			Button btnNewButton = new Button(container, SWT.NONE);
			btnNewButton.addMouseListener(new MouseAdapter() {
				private static final long serialVersionUID = -6160643742119261652L;

				@Override
				public void mouseUp(MouseEvent e) {
					selectPage();
				}
			});
			btnNewButton.setText("Выбор страницы");
		}

		{
			Label lblChildrenPages = new Label(container, SWT.NONE);
			lblChildrenPages.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1));
			lblChildrenPages.setText("Потомки:");

			this.listViewer = new ListViewer(container, SWT.BORDER | SWT.V_SCROLL);
			List listChildrenPages = this.listViewer.getList();
			listChildrenPages.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

			this.listViewer.setContentProvider(new ArrayContentProvider());
			this.listViewer.setLabelProvider(new ViewLabelProvider());
			this.listViewer.setSorter(new ViewerSorter() {
				private static final long serialVersionUID = 6771589845098316511L;

				@Override
				public int compare(Viewer viewer1, Object e1, Object e2) {
					if (e1 instanceof WikiPage && e2 instanceof WikiPage) {
						String s1 = ((WikiPage) e1).getName();
						String s2 = ((WikiPage) e2).getName();
						return s1.compareTo(s2);
					}
					return super.compare(viewer1, e1, e2);
				}

			});

			this.listViewer.setInput(this.childrenPages);

			Button btnNewButton_1 = new Button(container, SWT.NONE);
			btnNewButton_1.addMouseListener(new MouseAdapter() {
				private static final long serialVersionUID = 5756098312399721871L;

				@Override
				public void mouseUp(MouseEvent e) {
					selectPages();
				}
			});
			btnNewButton_1.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
			btnNewButton_1.setText("Выбор страниц");
		}

		return container;
	}

	/**
	 * Create contents of the button bar.
	 * 
	 * @param parent
	 */
	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		createButton(parent, IDialogConstants.OK_ID, "Ввод", true);
		createButton(parent, IDialogConstants.CANCEL_ID, "Отмена", false);
	}

	/**
	 * Return the initial size of the dialog.
	 */
	@Override
	protected Point getInitialSize() {
		return new Point(715, 545);
	}

	@Override
	protected void cancelPressed() {
		// TODO Auto-generated method stub
		super.cancelPressed();
	}

	@Override
	protected void okPressed() {
		// TODO Auto-generated method stub
		super.okPressed();
	}

	/**
	 * Выбор одной страницы.
	 */
	protected void selectPage() {
		PageManager pm = engine.getManager(PageManager.class);
		PageProvider pp = pm.getCurrentProvider();
		java.util.List<WikiPage> listWikiPages = pp.getRootPages();

		PagesSelectDialog pagesSelectDialog = new PagesSelectDialog(getShell(), Boolean.FALSE, listWikiPages);
		if (pagesSelectDialog.open() == Window.OK) {
			java.util.List<?> selectedPages;
			selectedPages = pagesSelectDialog.getSelectedPages();
			if (selectedPages.size() > 0) {
				this.masterPage = (WikiPage) selectedPages.get(0);
				this.textMasterPage.setText(this.masterPage.getName());

				// Удалить из списка Children-страниц выбранную Master-страницу.
				CDOID masterPageID = this.masterPage.cdoID();
				for (WikiPage page : this.childrenPages) {
					if (masterPageID.equals(page.cdoID())) {
						this.childrenPages.remove(page);
						this.listViewer.refresh(true);
						break;
					}
				}
			}
		}
	}

	/**
	 * Выбор нескольких страниц.
	 */
	@SuppressWarnings("unchecked")
	protected void selectPages() {
		PageManager pm = engine.getManager(PageManager.class);
		PageProvider pp = pm.getCurrentProvider();
		java.util.List<WikiPage> listWikiPages = pp.getRootPages();

		PagesSelectDialog pagesSelectDialog = new PagesSelectDialog(getShell(), Boolean.TRUE, listWikiPages);
		if (pagesSelectDialog.open() == Window.OK) {
			java.util.List<WikiPage> selectedPages;
			selectedPages = (java.util.List<WikiPage>) pagesSelectDialog.getSelectedPages();
			if (selectedPages.size() > 0) {
				if (this.masterPage != null) {
					// Удалить из списка выбранного уже выбранную Master-страницу.
					CDOID masterPageID = this.masterPage.cdoID();
					for (WikiPage page : selectedPages) {
						if (!masterPageID.equals(page.cdoID())) {
							this.childrenPages.add(page);
						}
					}
				} else {
					this.childrenPages.addAll(selectedPages);
				}
				this.listViewer.refresh(true);
			}
		}
	}

	public WikiPage getMasterPage() {
		return this.masterPage;
	}

	public java.util.List<WikiPage> getChildrenPages() {
		return this.childrenPages;
	}

}
